// ****************************************************************
// This is free software licensed under the NUnit license. You
// may obtain a copy of the license as well as information regarding
// copyright ownership at http://nunit.org.
// ****************************************************************

namespace GenReportAddin
{
	using System;
	using System.Globalization;
	using System.IO;
	using System.Xml;
	using System.Collections;
	using System.Reflection;
	using NUnit.Core;

	/// <summary>
	/// Summary description for XmlResultWriter.
	/// </summary>
	public class XmlResultWriter
	{
		private XmlTextWriter xmlWriter;
		private TextWriter writer;
		private MemoryStream memoryStream;

		#region Constructors
		public XmlResultWriter(string fileName)
		{
			String directory = "C:\\CE_TestReport\\";
			if (!Directory.Exists(directory))
				Directory.CreateDirectory(directory);

			String filePath = directory + fileName;
			xmlWriter = new XmlTextWriter(new StreamWriter(filePath, false, System.Text.Encoding.UTF8));
		}

		public XmlResultWriter(TextWriter writer)
		{
			this.memoryStream = new MemoryStream();
			this.writer = writer;
			this.xmlWriter = new XmlTextWriter(new StreamWriter(memoryStream, System.Text.Encoding.UTF8));
		}
		#endregion


		#region Public Methods
		public void SaveTestResult(TestResult result)
		{
			ArrayList test_cases = new ArrayList();
			GetAll_TestCase(result, test_cases);

			WriteResultElement(test_cases);
		}

		private void GetAll_TestCase(TestResult result, ArrayList test_cases)
		{
			if (result.HasResults)
			{
				if ("ParameterizedTest".Equals(result.Test.TestType))
				{
					test_cases.Add(result);
				}
				else
				{
					foreach (TestResult childResult in result.Results)
						GetAll_TestCase(childResult, test_cases);
				}
			}
			else
			{

				if (!result.Test.IsSuite)
					test_cases.Add(result);
			}
		}

		private void WriteResultElement(ArrayList test_cases_result)
		{
			//foreach (TestResult test_case_result in test_cases_result)
			//{

			//    Console.WriteLine(test_case_result.FullName);
			//}

			xmlWriter.Formatting = Formatting.Indented;
			xmlWriter.WriteStartDocument(true);
			xmlWriter.WriteStartElement("test-cases");

			int count = 0;
			foreach (TestResult test_case_result in test_cases_result)
			{

				xmlWriter.WriteStartElement("test-case");

				xmlWriter.WriteAttributeString("no", (++count).ToString());

				xmlWriter.WriteAttributeString("asset", Get_Asset(test_case_result.FullName));
				xmlWriter.WriteAttributeString("fixture", Get_FixtureName(test_case_result.FullName));
				xmlWriter.WriteAttributeString("test_case_name", Get_MethodName(test_case_result.FullName));
				xmlWriter.WriteAttributeString("result", Get_Result(test_case_result));
				xmlWriter.WriteAttributeString("message", test_case_result.Message);
				xmlWriter.WriteEndElement();
			}

			TerminateXmlFile();
		}

		private string Get_Result(TestResult test_case_result)
		{
			if (test_case_result.IsSuccess)
				return "success";
			else if (test_case_result.IsFailure)
				return "failure";
			else if (test_case_result.IsError)
				return "error";
			else
				return String.Empty;
		}

		private String Get_Asset(String fullName)
		{
			if (String.IsNullOrEmpty(fullName))
				return String.Empty;
			else
			{
				String[] namespaces = fullName.Split(new char[] { '.' });
				return namespaces[3];
			}
		}

		private String Get_FixtureName(String fullName)
		{
			if (String.IsNullOrEmpty(fullName))
				return String.Empty;
			else
			{
				String[] namespaces = fullName.Split(new char[] { '.' });
				return namespaces[namespaces.Length - 2];
			}
		}

		private String Get_MethodName(String fullName)
		{
			if (String.IsNullOrEmpty(fullName))
				return String.Empty;
			else
			{
				String[] namespaces = fullName.Split(new char[] { '.' });
				return namespaces[namespaces.Length - 1];
			}
		}

		private void TerminateXmlFile()
		{
			try
			{
				xmlWriter.WriteEndElement(); // test-results
				xmlWriter.WriteEndDocument();
				xmlWriter.Flush();

				if (memoryStream != null && writer != null)
				{
					memoryStream.Position = 0;
					using (StreamReader rdr = new StreamReader(memoryStream))
					{
						writer.Write(rdr.ReadToEnd());
					}
				}

				xmlWriter.Close();
			}
			catch (Exception e)
			{
				Console.WriteLine(e.Message);
				Console.WriteLine(e.StackTrace);
			}
			finally
			{
				//writer.Close();
			}
		}
		#endregion
	}

}
